package com.matt.service.impl;


import com.dotflat.util.excelUtil.ExcelDataVo;
import com.matt.commons.dto.sso.StaffDTO;
import com.matt.commons.exception.BusinessException;
import com.matt.domain.ChildActivity;
import com.matt.domain.Classes;
import com.matt.domain.UserActiveRegistration;
import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.query.ChildrenActiveQuery;
import com.matt.foundation.utils.DateUtil;
import com.matt.foundation.vo.ChildActivityVo;
import com.matt.repository.ChildActivityRepository;
import com.matt.repository.ChildActivitySpecification;
import com.matt.repository.ClassesRepository;
import com.matt.repository.UserActiveRegistrationRepository;
import com.matt.repository.base.BaseNativeSqlRepository;
import com.matt.service.ChildActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * (ChildActivity)表服务实现类
 *
 * @author makejava
 * @since 2025-02-21 15:04:17
 */
@Service("childActivityService")
public class ChildActivityServiceImpl extends BaseNativeSqlRepository implements ChildActivityService {
    @Autowired
    ChildActivityRepository childActivityRepository;
    @Autowired
    UserActiveRegistrationRepository userActiveRegistrationRepository;
    @Autowired
    ClassesRepository classesRepository;

//    @Override
//    public Object add(ChildActivity childActivity) {
//        DateUtil.parseToDateHour(childActivity.getStartTime())
//        ChildActivity activity=new ChildActivity();
//        activity.setCreateTime(new Date());
//        return null;
//    }

    @Override
    public Object addOrUpdate(String title, String classIds, String type, String address, String startTime, String endTime, String deadlineTime, String content, String remark, StaffDTO ticket, String id, Integer source) {
        ChildActivity activity = new ChildActivity();
        if (id != null) {
            activity = childActivityRepository.findById(id).get();
        } else {
            activity.setCreateTime(new Date());
        }
        activity.setTitle(title);
        activity.setClassIds(classIds);
        activity.setType(type);
        activity.setAddress(address);
        activity.setStartTime(DateUtil.parseToDateHour(startTime));
        activity.setEndTime(DateUtil.parseToDateHour(endTime));
        activity.setDeadlineTime(DateUtil.parseToDateHour(deadlineTime));
        activity.setContent(content);
        activity.setRemark(remark);
        activity.setAreaId(ticket.getAreaId());
        activity.setSourceType(source);
        childActivityRepository.save(activity);
        return null;
    }

    @Transactional
    @Override
    public boolean delete(String id, String areaId) {
        try {
            Long size = userActiveRegistrationRepository.findCountByAreaIdAndActivityId(
                    areaId, id);
            if (size > 0) {
                throw new BusinessException(ErrorCode.DELETE_ERROR, "该活动已有报名，无法删除！");
            }
            ;
            //先删除子表
            userActiveRegistrationRepository.deleteByActivityId(id);
            //在删除主表
            childActivityRepository.deleteById(id);
        } catch (Exception e1) {
            throw new BusinessException(ErrorCode.DELETE_ERROR, "活动通告失败！");
        }
        return true;
    }

    @Override
    public List<ExcelDataVo> export(String id, String areaId) {
        ChildActivity activity = childActivityRepository.findById(id).get();

        List<UserActiveRegistration> allByActivityIdAndAreaId = userActiveRegistrationRepository.findAllByActivityIdAndAreaIdAndIsActiveTrue(id, areaId);
        //列名称
        List<String> titleList = new ArrayList<>();
        titleList.add("宝宝姓名");
        titleList.add("所属关系");
        titleList.add("报名人");
        titleList.add("联系电话");
        titleList.add("报名时间");


        //属性名称
        List<String> attributeList = new ArrayList<>();
        attributeList.add("childrenName");
        attributeList.add("relation");
        attributeList.add("userName");
        attributeList.add("phone");
        attributeList.add("registerTime");
        // 封装需要导出的数据
        List<ExcelDataVo> excelDataVoList = new ArrayList<>();

        String activityTile = "";
        activityTile = activity.getTitle();
        // 封装学生信息
        ExcelDataVo excelDataSheetOne = new ExcelDataVo();
        excelDataSheetOne.setSheetName(activityTile);
        excelDataSheetOne.setSheetTopColHeaderTitle(activityTile + "报名信息统计");
        excelDataSheetOne.setSheetTopColHeaderName(titleList.toArray(new String[titleList.size()]));
        // 使用 DateTimeFormatter 格式化日期
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(java.time.ZoneId.of("GMT+8"));
        excelDataSheetOne.setSheetTopColHeaderAttribute(attributeList.toArray(new String[attributeList.size()]));
        List<Map<String, Object>> mapList = allByActivityIdAndAreaId.stream().map(it -> {
            Map<String, Object> apiMap = new HashMap<>();
            apiMap.put("childrenName", it.getChildrenName());
            apiMap.put("relation", it.getRelation());
            apiMap.put("userName", it.getUserName());
            apiMap.put("phone", it.getPhone());
            // 格式化 registerTime 去掉毫秒部分
            if (it.getRegisterTime() != null) {
                // 如果使用 Java 8 的 LocalDateTime
                LocalDateTime localDateTime = it.getRegisterTime().toInstant().atZone(java.time.ZoneId.of("GMT+8")).toLocalDateTime();
                apiMap.put("registerTime", localDateTime.format(formatter));
            } else {
                apiMap.put("registerTime", "");
            }
            return apiMap;
        }).collect(Collectors.toList());
        excelDataSheetOne.setSheetDataList(mapList);
        excelDataVoList.add(excelDataSheetOne);
        return excelDataVoList;
    }

    @Override
    public List<ChildActivityVo> activeList(String areaId, String roleName, List<String> userId) {
        // Step 1: 获取所有需要的班级ID
        Set<String> allClassIds = new HashSet<>();
        if (!"园长".equals(roleName)) {
            Specification<com.matt.domain.ChildActivity> specification = ChildActivitySpecification.buildSpecification(areaId, userId);
            List<com.matt.domain.ChildActivity> activities = childActivityRepository.findAll(specification);
            for (com.matt.domain.ChildActivity activity : activities) {
                if (activity.getClassIds() != null && !activity.getClassIds().isEmpty()) {
                    allClassIds.addAll(Arrays.asList(activity.getClassIds().split(",")));
                }
            }
        }

        // Step 2: 批量查询班级信息
        Map<String, Classes> classesMap = classesRepository.findAllById(allClassIds).stream()
                .collect(Collectors.toMap(Classes::getId, Function.identity()));

        // Step 3: 查询活动列表
        List<Object[]> results;
        if (!"园长".equals(roleName)) {
            Specification<com.matt.domain.ChildActivity> specification = ChildActivitySpecification.buildSpecification(areaId, userId);
            results = childActivityRepository.findAll(specification).stream()
                    .map(activity -> new Object[]{
                            activity.getTitle(),
                            activity.getClassIds(),
                            activity.getType(),
                            activity.getAddress(),
                            activity.getStartTime(),
                            activity.getEndTime(),
                            activity.getDeadlineTime(),
                            activity.getContent(),
                            activity.getRemark(),
                            activity.getAreaId(),
                            activity.getSourceType(),
                            activity.getCreateTime(),
                            activity.getId()
                    })
                    .collect(Collectors.toList());
        } else if ("园长".equals(roleName)) {
            results = childActivityRepository.findByQueryNew(areaId);
        } else {
            results = new ArrayList<>();
        }

        // Step 4: 转换为VO对象，并填充classNames和activeSize
        List<ChildActivityVo> list = results.stream()
                .map(result -> {
                    ChildActivityVo vo = new ChildActivityVo();
                    vo.setTitle((String) result[0]);
                    vo.setClassIds((String) result[1]);
                    vo.setType((String) result[2]);
                    vo.setAddress((String) result[3]);
                    vo.setStartTime(result[4] != null ? (Date) result[4] : null);
                    vo.setEndTime(result[5] != null ? (Date) result[5] : null);
                    vo.setDeadlineTime(result[6] != null ? (Date) result[6] : null);
                    vo.setContent((String) result[7]);
                    vo.setRemark((String) result[8]);
                    vo.setAreaId((String) result[9]);
                    vo.setSourceType(result[10] != null ? ((Number) result[10]).intValue() : null);
                    vo.setCreateTime(result[11] != null ? (Date) result[11] : null);
                    vo.setId((String) result[12]);

                    // 根据classIds获取classNames
                    if (vo.getClassIds() != null && !vo.getClassIds().isEmpty()) {
                        List<String> classNames = Arrays.stream(vo.getClassIds().split(","))
                                .map(String::trim)
                                .filter(classId -> !classId.isEmpty())
                                .map(classesMap::get)
                                .filter(Objects::nonNull)
                                .map(Classes::getName)
                                .collect(Collectors.toList());
                        vo.setClassNames(String.join(", ", classNames));
                    }

                    Long size = userActiveRegistrationRepository.findCountByAreaIdAndActivityId(
                            areaId, vo.getId()
                    );
                    vo.setActiveSize(size);
                    return vo;
                })
                .collect(Collectors.toList());

        return list;
    }

//    @PersistenceContext
//    private EntityManager entityManager;
//    private List<Object[]> dynamicFindByQueryNew1(String areaId, List<String> classIds) {
//        StringBuilder querySqlBuilder = new StringBuilder();
//        querySqlBuilder.append("SELECT ")
//                .append("ca.title, ")
//                .append("ca.classIds, ")
//                .append("ca.type, ")
//                .append("ca.address, ")
//                .append("ca.startTime, ")
//                .append("ca.endTime, ")
//                .append("ca.deadlineTime, ")
//                .append("ca.content, ")
//                .append("ca.remark, ")
//                .append("ca.areaId, ")
//                .append("ca.sourceType, ")
//                .append("ca.createTime, ")
//                .append("ca.id ")
//                .append("FROM child_activity ca ")
//                .append("WHERE (:areaId IS NULL OR ca.areaId = :areaId) ");
//
//        if (classIds != null && !classIds.isEmpty()) {
//            querySqlBuilder.append("AND (");
//            for (int i = 0; i < classIds.size(); i++) {
//                if (i > 0) {
//                    querySqlBuilder.append(" OR ");
//                }
//                querySqlBuilder.append("ca.classIds LIKE CONCAT('%', :classId").append(i).append(", '%')");
//            }
//            querySqlBuilder.append(")");
//        }
//
//        querySqlBuilder.append(" ORDER BY ca.createTime DESC");
//
//        String querySql = querySqlBuilder.toString();
//
//        // 创建并设置查询参数
//        Query query = entityManager.createNativeQuery(querySql);
//        query.setParameter("areaId", areaId);
//
//        if (classIds != null && !classIds.isEmpty()) {
//            for (int i = 0; i < classIds.size(); i++) {
//                query.setParameter("classId" + i, classIds.get(i));
//            }
//        }
//
//        // 执行查询并返回结果
//        return query.getResultList();
//    }
//
//    @Override
//    public List<ChildActivityVo> activeList(String areaId, String roleName, List<String> userId) {
//        List<Object[]> results = new ArrayList<>();
//
//        if ("班主任".equals(roleName)) {
//            results = dynamicFindByQueryNew1(areaId, userId);
//        } else if ("园长".equals(roleName)) {
//            // 假设 childActivityRepository.findByQueryNew 是另一个查询方法
//            results = childActivityRepository.findByQueryNew(areaId);
//        }
//
//        // 转换为VO对象，并填充classNames
//        List<ChildActivityVo> list = results.stream()
//                .map(result -> {
//                    ChildActivityVo vo = new ChildActivityVo();
//                    vo.setTitle((String) result[0]);
//                    vo.setClassIds((String) result[1]);
//                    vo.setType((String) result[2]);
//                    vo.setAddress((String) result[3]);
//                    vo.setStartTime(result[4] != null ? (Date) result[4] : null);
//                    vo.setEndTime(result[5] != null ? (Date) result[5] : null);
//                    vo.setDeadlineTime(result[6] != null ? (Date) result[6] : null);
//                    vo.setContent((String) result[7]);
//                    vo.setRemark((String) result[8]);
//                    vo.setAreaId((String) result[9]);
//                    vo.setSourceType(result[10] != null ? ((Number) result[10]).intValue() : null);
//                    vo.setCreateTime(result[11] != null ? (Date) result[11] : null);
//                    vo.setId((String) result[12]);
//
//                    // 根据classIds获取classNames
//                    if (vo.getClassIds() != null && !vo.getClassIds().isEmpty()) {
//                        List<String> classNames = Arrays.stream(vo.getClassIds().split(","))
//                                .map(String::trim)
//                                .filter(classId -> !classId.isEmpty())
//                                .map(classId -> classesRepository.findById(classId).orElse(null))
//                                .filter(Objects::nonNull)
//                                .map(Classes::getName)
//                                .collect(Collectors.toList());
//                        vo.setClassNames(String.join(", ", classNames));
//                    }
//
//                    Long size = userActiveRegistrationRepository.findCountByAreaIdAndActivityId(
//                            areaId, vo.getId()
//                    );
//                    vo.setActiveSize(size);
//                    return vo;
//                })
//                .collect(Collectors.toList());
//
//        return list;
//    }


    @Override
    public Page<ChildActivityVo> page(ChildrenActiveQuery query) {
        int pageNum = query.getPageNum();
        int pageSize = query.getPageSize();

        // 获取所有符合条件的活动记录
        List<Object[]> results = childActivityRepository.findByQueryNew(query.getAreaId());

        // 计算总条数
        Long count = (long) results.size();

        // 分页处理
        int fromIndex = Math.min(pageNum * pageSize, results.size());
        int toIndex = Math.min(fromIndex + pageSize, results.size());
        List<Object[]> pagedResults = results.subList(fromIndex, toIndex);

        // 转换为VO对象，并填充classNames
        List<ChildActivityVo> list = pagedResults.stream()
                .map(result -> {
                    ChildActivityVo vo = new ChildActivityVo();
                    vo.setTitle((String) result[0]);
                    vo.setClassIds((String) result[1]);
                    vo.setType((String) result[2]);
                    vo.setAddress((String) result[3]);
                    vo.setStartTime(result[4] != null ? (Date) result[4] : null);
                    vo.setEndTime(result[5] != null ? (Date) result[5] : null);
                    vo.setDeadlineTime(result[6] != null ? (Date) result[6] : null);
                    vo.setContent((String) result[7]);
                    vo.setRemark((String) result[8]);
                    vo.setAreaId((String) result[9]);
                    vo.setSourceType(result[10] != null ? ((Number) result[10]).intValue() : null);
                    vo.setCreateTime(result[11] != null ? (Date) result[11] : null);
                    vo.setId((String) result[12]);

                    // 根据classIds获取classNames
                    if (vo.getClassIds() != null && !vo.getClassIds().isEmpty()) {
                        List<String> classNames = Arrays.stream(vo.getClassIds().split(","))
                                .map(String::trim)
                                .filter(classId -> !classId.isEmpty())
                                .map(classId -> classesRepository.findById(classId).orElse(null))
                                .filter(Objects::nonNull)
                                .map(Classes::getName)
                                .collect(Collectors.toList());
                        vo.setClassNames(String.join(", ", classNames));
                    }

                    Long size = userActiveRegistrationRepository.findCountByAreaIdAndActivityId(
                            query.getAreaId(), vo.getId()
                    );
                    vo.setActiveSize(size);
                    return vo;
                })
                .collect(Collectors.toList());

        return new PageImpl<>(list, PageRequest.of(pageNum, pageSize), count);
    }

    @Override
    public Map getDetailByActiveId(String activeId, String areaId) {
        ChildActivity activity = childActivityRepository.findById(activeId).get();
        // 查找所有与该活动相关的报名记录
        List<UserActiveRegistration> registrations = userActiveRegistrationRepository.findAllByActivityIdAndAreaIdAndIsActiveTrue(activeId, areaId);
        // 解析 classIds 字段并获取班级名称
        List<String> classIdList = Arrays.asList(activity.getClassIds().split(","));
        List<Classes> classesList = classesRepository.findAllById(classIdList);

        // 创建一个Map来存储结果
        Map<String, Object> result = new HashMap<>();
        result.put("activity", activity); // 添加活动详情
        result.put("registrations", registrations); // 添加报名记录列表
        result.put("classnames", classesList.stream().map(Classes::getName).collect(Collectors.toList())); // 添加班级名称列表
        return result;
    }


}
